////////////////////////////////////////////////////////////////////////////////
// Этот файл показывает, какого стиля кодирования стоит придерживаться.
// Показанный стиль используют в библиотеке Qt от Nokia и Trolltech
////////////////////////////////////////////////////////////////////////////////

/**
 * @file coding_style.cpp
 * This file shows coding style
 * Use doxygen comments when possible, use comments to document behavior
 */

#include <list>
#include <vector>
#include <stdio.h>

/**
 * @brief The IErrorsListener class
 * All interfaces should have I prefix: IListener, IVisitor, IEditableObject
 */
class IErrorsListener
{
public:
    virtual void onError() = 0;
    
    // you should define virtual destructor when you use polymorphism
    virtual ~IErrorsListener() {}
};

/**
 * @brief The ErrorsDispatcher class
 * Classes should not have C prefix: ErrorsDispatcher, EchoListener, FlyBehavior,
 * but neither CErrorsDispatcher nor CFlyBehavior
 */
class ErrorsDispatcher
{
public:
    virtual ~ErrorsDispatcher() {}

    // name begins with lower case: notify(), not Notify()
    void notify()
    {
        // C++ 2011 features allowed
        for (auto item = _listeners.begin(); item != _listeners.end(); ++item)
        {
            (*item)->onError();
        }
    }

    /**
     * @brief addListener adds listener if it hasn't been added already
     * @param listener another object that should listen errors
     */
    void addListener(IErrorsListener *listener)
    {
        for (auto item = _listeners.begin(); item != _listeners.end(); ++item)
        {
            if (*item == listener)
                return;
        }
        _listeners.push_back(listener);
    }

    void removeListener(IErrorsListener *listener)
    {
        for (auto item = _listeners.begin(); item != _listeners.end(); ++item)
        {
            if (*item == listener)
            {
                _listeners.erase(item);
                break;
            }
        }
    }

private:
    // Use std::list instead of std::vector. In other words: use STL properly
    // Also, members has "_" prefix instead of "m_"
    std::list<IErrorsListener*> _listeners;
};

// every enumeration constant should use enum typename as prefix
enum Format {
    Format_SINGLE_LINES,
    Format_COMMA_SEPARATED,
    Format_SEMICOLON_SEPARATED
};

int main(int argc, char* argv[])
{
    puts("This is program command-line arguments:");
    
    // there we use int only because "argc" has type int
    for (int index = 1; index < argc; ++index)
    {
        puts(argv[index]);
    }
    
    std::vector<int> sample = {0, 1, 2, 3, 4};
    // there we use size_t because vector.size() returns size_t
    for (size_t index = 0; index < sample.size(); ++index)
    {
        printf("sample vector containts %d\n", sample[index]);
    }

    return 0;
}
